package eclipse.lib.map;
import java.awt.Color;

import javax.media.opengl.jgloo.jgl2d.*;
import javax.media.opengl.jgloo.jglsh.*;

import eclipse.Constants;
import eclipse.client.Database;
import eclipse.lib.scripting.*;
import eclipse.util.io.IOTools;
/*
 * Copyright (c) 2009, TOD Productions All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *	- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *	- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *	-Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
public final class MapFile extends ByteDecoder
{
	//TODO: Add reference to tile color to bytecode.
	//Map object associated with the MapFile object
	private Map map;
	//data of the MapFile in ByteArray form
	private ByteArray data;
	//This just tests the map file...
	public static void main(String args[])
	{
		final MapFile map = new MapFile();
		map.setLayerCount(5);
		map.setName("test map");
		map.setLightColor(0, 255, 155, 055);
		map.setLightEnabled(0, true);
		map.setLinkedMaps(10, 15, 20, 25);
		map.decode();
		
		System.out.println(map.getMap().getLayerCount());
		System.out.println(map.getMap().getName());
		System.out.println(map.getMap().getLightColor(0).getRed());
		System.out.println(map.getMap().getLightColor(0).getGreen());
		System.out.println(map.getMap().getLightColor(0).getBlue());
		System.out.println(map.getMap().isLightEnabled(0));
		System.out.println(map.getMap().getLinkedMaps().north);
	}
	/** 
	 * Builds the Map File object
	 */
	public MapFile()
	{
		//create an array to use by default
		data = new ByteArray();				
	}	
	public MapFile(Map map)
	{
		//create new array to use by default
		data = new ByteArray();
		//create a new map to use
		this.map = map;
		//set the number of layers to what the map specifies
		this.setLayerCount(map.getLayerCount());
		System.out.println(map.getLayerCount());
		//set the name to what the map specifies
		this.setName(map.getName());
		//set the music to what the map specifies
		this.setMusic(map.getMusic());
		//set the morality to what the map specifies
		this.setMorality(map.getMorality());
		//set the linked maps to what the map specifies
		this.setLinkedMaps(
			map.getLinkedMaps().north,
			map.getLinkedMaps().south,
			map.getLinkedMaps().east,
			map.getLinkedMaps().west);
		//set the respawn to what the map specifies
		this.setRespawn(
			map.getRespawn().map,
			map.getRespawn().x,
			map.getRespawn().y,
			map.getRespawn().height);
		//scroll through each light and add them
		for(int index = 0; index < 8; index++)
		{
			//get the color of each light
			Color color = map.getLightColor(index).toRGBColor();
			//set whether the light is enabled
			this.setLightEnabled(index, map.isLightEnabled(index));
			//set the color of the light
			this.setLightColor(index, color.getRed(), color.getGreen(), color.getBlue());			
		}
		//scroll through each layer in the map
		for(int index = 0; index < map.getLayerCount(); index++)
		{
			//get the layer object from the map
			final Layer layer = map.getLayer(index);
			//set the layer's visibility to what the map specifies
			this.setLayerVisibility(index, layer.isVisible());
			//scroll through each tile x
			for(int x = 0; x < 20; x++)
			{
				//scroll through each tile y
				for(int y = 0; y < 15; y++)
				{
					//get the tile object from the layer
					final JGLTile tile = layer.getTile(x, y);
					//set the tile's attribute
					this.setLayerAttribute(index, x, y, layer.getAttribute(x, y));
					//set the tile's texture
					this.setLayerTile(index, x, y, tile.sheet, tile.getX(), tile.getY());
					//set the tile's color					
					final Color color = tile.getColor().toRGBAColor();
					this.setTileColor(index, x, y, color.getRed(), color.getBlue(), color.getGreen(), color.getAlpha());
				}
			}			
		}
	}
	/**
	 * Returns the map that is associated with the MapFile
	 * @return Map object
	 */
	public Map getMap()
	{
		//return the Map Object
		return map;
	}
	/**
	 * dumps the data into a file
	 * @param sFile
	 */
	public final void save(String sFile)
	{		
		//saves the map as a file
		IOTools.writeBytesToFile(sFile, data.toArray());	
	}
	/**
	 * loads data from a file
	 * @param sFile
	 */
	public final Map open(String sFile)
	{
		//loads the map from a file
		data = new ByteArray(IOTools.readAsBytes(sFile));
		//decode the map
		decode();	
		//return the map file
		return map;
	}		
	public final void setLayerAttribute(int layer, int xLoc, int yLoc, TileAttribute attribute)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LAYERATTRIBUTE.getValue());
		//add the layer index
		data.appendTo(layer);
		//add the x-point
		data.appendTo(xLoc);
		//add the y-point
		data.appendTo(yLoc);
		//add the attribute byte
		data.appendTo(attribute.getValue());
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	public final void decodeLayerAttribute(ByteArray command)
	{
		//token used to parse the array
		int token	= 0;
		//pull the sub array and convert it to an integer
		final int layer	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull the sub array and convert it to an integer
		final int xloc	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull the sub array and convert it to an integer
		final int yloc 	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull the sub array and convert it to a byte
		final byte attb	= command.subArray(token, token + Constants.BYTESIZE).toByte();
		
		//set the map's layer's tile's attribute
		map.getLayer(layer).setAttribute(xloc, yloc, TileAttribute.getAttribute(attb));
	}
	/**
	 * Sets the values of a tile
	 * @param layer Layer index to edit
	 * @param xLoc x location of the tile on the layer
	 * @param yLoc y location of the tile on the layer
	 * @param tilesheet tilesheet index
	 * @param tx tile's x point on the tilesheet
	 * @param ty tile's y point on the tilesheet
	 */
	public final void setLayerTile(int layer, int xLoc, int yLoc, int tilesheet, int tx, int ty)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LAYERTILE.getValue());
		//add the layer index
		data.appendTo(layer);
		//add the tile x location value
		data.appendTo(xLoc);
		//add the tile y location value
		data.appendTo(yLoc);
		//add the tile sheet index
		data.appendTo(tilesheet);
		//add the tilesheet x source
		data.appendTo(tx);
		//add the tilesheet y source
		data.appendTo(ty);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Decodes the layer tiles
	 * @param command Command to decode
	 */
	public final void decodeLayerTile(ByteArray command)
	{
		//Token used to parse the array
		int token	= 0;		
		//pull a sub array and convert it to an integer
		final int layer	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int xloc	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int yloc	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int tilesht	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int tx		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int ty		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the texture
		map.getLayer(layer).getTile(xloc, yloc).setTexture(Database.tTileSheet[tilesht]);
		//update the tile's uv values
		map.getLayer(layer).getTile(xloc, yloc).setTile(tx, ty);
	}
	/**
	 * Sets the visibility of the layer
	 * @param layer Layer to modify the visibility of
	 * @param value True = visible, False = invisible
	 */
	public final void setLayerVisibility(int layer, boolean value)
	{
		//default value for the visibility byte
		byte val = 0;
		//if the value is true then change the value of that byte
		if(value = true)
		{
			//value of 1 = true
			val = 1;
		}
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LAYERVISIBLE.getValue());
		//add the layer 
		data.appendTo(layer);
		//add the value
		data.appendTo(val);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	public final void decodeLayerVisibility(ByteArray command)
	{
		//value determines whether it is visible
		boolean vis = false;
		
		//token used to parse the file
		int token 	= 0;
		//pull a sub array and convert it to integer
		final int layer 	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();

		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to a byte
		final byte visible= command.subArray(token, token + Constants.BYTESIZE).toByte();
		
		//if the value = 1 then change the value of vis
		if(visible == (byte) 1)
		{
			//it is visible
			vis = true;
		}
		
		//set the visibility of the layer
		map.getLayer(layer).setVisible(vis);
	}
	/**
	 * Sets the morality of the map
	 * @param morality Morality to set the map
	 */
	public final void setMorality(MapMorality morality)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.MORALITY.getValue());
		//add the morality byte
		data.appendTo(morality.getValue());
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Sets the map's morality from a command array
	 * @param Command to decode
	 */
	public final void decodeMorality(ByteArray command)
	{
		//pull the byte associated with morality
		final byte morality = command.toByte();
		//return the morality Object
		map.setMorality(MapMorality.getMorality(morality));
	}	
	/**
	 * Sets the respawn point for the map file
	 * @param map Map to respawn at
	 * @param x x-point
	 * @param y y-point
	 * @param height height
	 */
	public final void setRespawn(int map, int x, int y, int height)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.RESPAWN.getValue());
		//add the map index
		data.appendTo(map);
		//add the x point
		data.appendTo(x);
		//add the y point
		data.appendTo(y);
		//add the height
		data.appendTo(height);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Decode the respawn for the map
	 * @param command Command to decode
	 */
	public final void decodeRespawn(ByteArray command)
	{
		//token used for parsing
		int token	= 0;
		//pull a sub array and convert it to an integer
		final int map		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();

		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int x		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();

		//update the token
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to an integer
		final int y		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token		= token + Constants.INTEGERSIZE;
		final int height	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//set the respawn
		this.map.setRespawn(map, x, y, height);
	}
	/**
	 * Sets the maps adjacent to the current map
	 * @param north Map above this map
	 * @param south Map below this map
	 * @param east Map right of this map
	 * @param west Map left of this map
	 */
	public final void setLinkedMaps(int north, int south, int east, int west)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LINKEDMAPS.getValue());
		//add north map index
		data.appendTo(north);
		//add south map index
		data.appendTo(south);
		//add east map index
		data.appendTo(east);
		//add west map index
		data.appendTo(west);
		//add end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Decodes the linked maps
	 * @param command Command to decode
	 */
	public final void decodeLinkedMaps(ByteArray command)
	{
		//token used to parse the array
		int token	= 0;
		//pull a sub array and set it to an integer
		final int north	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token 		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to an integer
		final int south	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token 		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to an integer
		final int east	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token
		token 		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to an integer
		final int west	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//set the corresponding values in the map Object
		map.setLinkedMaps(north, south, east, west);
	}
	/**
	 * Sets the color of the light
	 * @param light light index
	 * @param r red value
	 * @param g green value
	 * @param b blue value
	 */
	public final void setLightColor(int light, int r, int g, int b)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LIGHTCOLOR.getValue());
		//add the light index 
		data.appendTo(light);
		//add the red value
		data.appendTo(r);
		//add the green value
		data.appendTo(g);
		//add the blue value
		data.appendTo(b);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Sets the color for a tile.
	 * @param layer layer of the tile
	 * @param x x-pos of tile
	 * @param y y-pos of tile
	 * @param r red value [0, 255]
	 * @param g green value [0, 255]
	 * @param b blue value [0, 255]
	 * @param a alpha value [0, 255]
	 */
	public final void setTileColor(int layer, int x, int y, int r, int g, int b, int a)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the map code
		data.appendTo(MapCode.LAYERTILECOLOR.getValue());
		//add the layer
		data.appendTo(layer);
		//add the x value
		data.appendTo(x);
		//add the y value
		data.appendTo(y);
		//add the red value
		data.appendTo(r);
		//add the green value
		data.appendTo(g);
		//add the blue value
		data.appendTo(b);
		//add the alpha value
		data.appendTo(a);
		//add the end byte
		data.appendTo(Constants.com_END);		
	}
	public final void decodeTileColor(ByteArray command)
	{
		//token used to parse the array
		int token = 0;
		//pull a sub array and set it to an integer
		final int layer = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;	
		//pull a sub array and set it to an integer
		final int x = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;		
		//pull a sub array and set it to an integer 
		final int y = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;		
		//pull a sub array and set it to an integer
		final int r = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;		
		//pull a sub array and set it to an integer
		final int g = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;		
		//pull a sub array and set it to an integer
		final int b = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;		
		//pull a sub array and set it to an integer
		final int a = command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		
		map.getLayer(layer).getTile(x, y).setColor(new JGLColor(a, r, g, b));
	}
	/**
	 * Decodes the light color
	 * @param command Command to decode
	 */
	public final void decodeLightColor(ByteArray command)
	{
		//token used to parse the array
		int token	= 0;
		//pull a sub array and set it to an integer
		final int light 	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();

		//update the token 
		token		= token + Constants.INTEGERSIZE;
		
		//pull a sub array and set it to an integer
		final int r		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to an integer
		final int g		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token 
		token		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to an integer
		final int b		= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//set the light color
		map.setLightColor(light, new JGLColor(new Color(r, g, b)));		
	}
	/**
	 * Sets a light's enabled state within a map
	 * @param light Light to enable or disable
	 * @param value True = enabled, False = disabled
	 */
	public final void setLightEnabled(int light, boolean value)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LIGHTENABLED.getValue());
		//add the light index integer
		data.appendTo(light);
		//add the light enabled byte
		if(value = false)
			data.appendTo((byte)0);
		else
			data.appendTo((byte)1);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	
	/**
	 * Decodes the status on a specific light
	 * @param command Command to decode
	 */
	public final void decodeLightEnabled(ByteArray command)
	{
		//token used to parse the array
		int token	= 0;
		//pull a sub array and set it to an integer
		final int light	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();

		//update the token's position
		token 		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to a byte
		final byte on 	= command.subArray(token, token + Constants.BYTESIZE).toByte();
		
		//set the default to off
		boolean enabled = false;
		//determine if the light is enabled
		if(on == (byte)1)
		{
			//it is, so enable it
			enabled = true;
		}
		//set the light's enabled status within the map file.
		map.setLightEnabled(light, enabled);
	}
	/**
	 * Sets the name of the music for the map
	 * @param music String to set the music to
	 */
	public final void setMusic(String music)
	{
		if(music == null)
			return;
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.MUSIC.getValue());
		//add the length of the string
		data.appendTo(music.length());
		//add the string
		data.appendTo(music);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Decodes the music path from the command array
	 * @param command Command to decode
	 */
	public final void decodeMusic(ByteArray command)
	{
		//token used to parse the array
		int token 	= 0;
		//pull a sub array and set it to an integer
		final int size  	= command.subArray(token, token + Constants.INTEGERSIZE).toInt();
		
		//update the token		
		token 		= token + Constants.INTEGERSIZE;
		//pull a sub array and set it to String
		final String music = command.subArray(token, token + size).toString();
		
		//update the map's music
		map.setMusic(music);
	}
	/**
	 * Sets the name of the map in the MapFile
	 * @param name String to set the map's name to
	 */
	public final void setName(String name)
	{
		if(name == null)
			return;
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.NAME.getValue());
		//add the length of the string
		data.appendTo(name.length());
		//add the string
		data.appendTo(name);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	/**
	 * Decode's the name from raw data
	 * @param command Raw data to decode
	 */
	public final void decodeName(ByteArray command)
	{
		//token used to parse the array
		int token	= 0;
		//pull a sub array and convert it to an integer
		final int size 	= command.subArray(token, Constants.INTEGERSIZE).toInt();
		
		//update the token		
		token 		=  token + Constants.INTEGERSIZE;
		//pull a sub array and convert it to a String
		final String name = command.subArray(token, token + size).toString();
		
		//update the map's name
		map.setName(name);
	}
	public final void setLayerCount(int count)
	{
		//add the start byte
		data.appendTo(Constants.com_START);
		//add the code byte
		data.appendTo(MapCode.LAYERCOUNT.getValue());
		//add the number of layers
		data.appendTo(count);
		//add the end byte
		data.appendTo(Constants.com_END);
	}
	public final void decodeLayerCount(ByteArray command)
	{
		//pull the integer from the array		
		final int intLayer = command.subArray(0, Constants.INTEGERSIZE).toInt();
		//save the layer size
		map = new Map("", intLayer);
	}
	/**
	 * Parser parses a ByteArray and stores the data into a map.
	 */
	public final void parser(ByteArray command) 
	{
		//find the code to run
		final MapCode code = MapCode.getMapCode(command.toArray()[0]);
		//remove the first byte
		command = command.subArray(1, command.length());
		//check if there is a code to decode
		if(code == MapCode.NONE)
		{
			//there is no code so return
			return;
		}
		//check if the code sets the Map's name
		else if(code == MapCode.NAME)
		{
			//decode the name of the map
			decodeName(command);
		}
		//check if the code sets the Map's music
		else if(code == MapCode.MUSIC)
		{
			//decode the music of the map
			decodeMusic(command);
		}
		//check if the code sets the number of layers in the map
		else if(code == MapCode.LAYERCOUNT)
		{
			//decode the number of layers in the map
			decodeLayerCount(command);
		}
		//check if the code sets the Morality of the map
		else if(code == MapCode.MORALITY)
		{
			//decode the morality of the map
			decodeMorality(command);
		}
		//check if the code sets whether lights are enabled
		else if(code == MapCode.LIGHTENABLED)
		{
			//decode the light enabled values of the map
			decodeLightEnabled(command);
		}
		//check if the code sets which maps are linked
		else if(code == MapCode.LINKEDMAPS)
		{
			//decode the linked maps
			decodeLinkedMaps(command);
		}
		//check if the code sets the color of the lights
		else if(code == MapCode.LIGHTCOLOR)
		{
			//decode the color of the maps
			decodeLightColor(command);
		}
		//check if the code sets the respawn point
		else if(code == MapCode.RESPAWN)
		{
			//decode the respawn point of the map
			decodeRespawn(command);
		}
		//check if the code sets the visible layers
		else if(code == MapCode.LAYERVISIBLE)
		{
			//decode if the layers are visible
			decodeLayerVisibility(command);
		}
		//check if the code sets the layer's tile
		else if(code == MapCode.LAYERTILE)
		{
			//decode the layer's tile
			decodeLayerTile(command);		
		}
		//check if the code sets the layer's attribute
		else if(code == MapCode.LAYERATTRIBUTE)
		{
			//decode the layer's attribute		
			decodeLayerAttribute(command);
		}
		//check if the code sets the tile's color.
		else if(code == MapCode.LAYERTILECOLOR)
		{
			//decode the layer's color
			decodeTileColor(command);
		}
		
	}		
	/**
	 * Wrapper method for decode(ByteArray)
	 * This allows the map to be decoded by using MapFile's default data
	 */
	public final void decode()
	{
		//call the ancestor's decode function
		super.decode(data);
	}
}
